{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit Scratch;

interface

implementation

(* TODO... migrate all of these notes to Issues list on GoogleCode. Ideally
   this file should then be deleted as it doesn't promote collaborative working *)

(*
bug:
changes to size of styles does not reflect new dimensions in object inspector
*)

(*
TODO: savediffsasxml method needs to test object contents rather than instance pointer in some cases,
well those where we use assigncontents method to copy inherited items. So we should add a virtual
equals function to TAHMUIObject and use that to perform comparison. Default implementation can be a
simple = test, we can then override that as necessary for various objects as required.

*)

(*
ipod scrolling

further tweaks...

when scrolling with mouse button held down, scroll offset matches
mouse position irrespective of scroll speed. when mouse is up the
current movement speed is preserved.

can also scroll past boundaries, but scroll distance is halved to
apply a braking effect. releasing mouse button bounces back to
first valid item.
*)

(*
overriding theme contents.

use cases:
1. override theme with user customisations
2. support user extensions - new screens - readily
3. support include/library theme content


current functionality:
have base and custom descriptors.
custom descriptor can use base descriptor content.
overriding base content only works accidentally for some animations & macros.

so, overrides apart, we can add include files - this will just clean up the
bloated interface and visual descriptor. includes must be chained to the front
of base descriptor in the order includes are listed.

this might work for overrides of simple elements such as position & colour.

we would like to reference included content in our descriptor - e.g. osk
but for us to override osk position then we would need to define a replacement
position in our descriptor. so the included descriptor would need to query our
descriptor for any overridden versions of content.

this can only work if we move to a late binding model for all ui elements. thats
a fair bit of work but we could do it incrementally as we need to. xml parsing
would store name of linked property, then when we need to refer to that property
we perform the lookup - so we need to build a property getter. that would work
fine at runtime, but introduces its own problems for the theme editor. perhaps
this is all a bit of overkill.

for now we can just look at adding include support. just need to decide how we
order and chain the include files together. and how we resolve duplicates and
removing dependencies.

duplicates are a pain... say we have osk include, and two different position
overrides for music and weather. in order to have both working we either need
to unload the include and reload when we swap descriptor, or keep a private
copy for each descriptor in memory, or query the included object continuously,
or update the linked objects when we load a new descriptor. latter is probably
the best approach. quite a bit of work though.

so... we won't have duplicate includes. do we add an include tag in each descriptor
or do we load all includes once in includes folder, or define these in theme
descriptor. if descriptors include other descriptors then we need to build a
check for circular references. if we just load all of the include files then that
should be pretty easy to implement, and make the themes a little easier to work
on.

so, we'll do that.

add an includes folder.

theme manager will load all include files as base elements of the base descriptors.

that should be all we need for now. theme manager will need some other mechanism
to determine base descriptor - ideally we want to show the descriptor name in the
theme designer.

add a node for includes files in the designer - either that or show a different icon
*)

(* plugin messages...

WM_NCPAINT - paint window frame
WM_NCCALCSIZE - size and position of client area must be calculated
WM_NCACTIVATE - non client area needs to be changed to active/inactive state
WM_NCHITTEST - sent to window when cursor moves or mouse is pressed or released.
   may be sent to captured window if mouse is captured
WM_NCLBUTTONUP - left mouse button released in non client area
WM_NCLBUTTONDOWN - left mouse button pressed in non client area
WM_NCLBUTTONDBLCLK - left mouse button was double clicked
WM_NCRBUTTONUP
WM_NCRBUTTONDOWN
WM_NCMOUSEMOVE
WM_GETMINMAXINFO - sent when size/position is about to change
WM_ACTIVATE - sent when window is activated/deactivated

*)

(*
theme restart thoughts...

need ability to change theme on the fly.

issues - will have to restart in home screen since we don't have consistent screen names. Should we?
pros/cons - consistent to do that, but limiting? could attempt to load module/screen with same name if it exists,
otherwise will have to default to default module screen or home screen - encourages but does not enforce naming convention.

requirements - seamless restart for resolution or fullscreen change. seamless restart for theme change. leave media playing.

looks easy enough to implement - need WarmRestart method (maybe call it UIRestart or something - "Reset"?)



would be nice to have pics changing on the fly in the background, select pic from picture grid or even run slideshow underneath.


theme stuff:
2. add gfx equaliser screen. -- check how many bands we need, maybe add bass boost, auto volume adjust.
3. add clock adjustment screen -- maybe date too. summertime checkbox


dsp effects:

dynamic amplify:
enabled checkbox
maximum amplification: 1.0 - 20.0 in 0.1 steps
attack 0.0db - 10.0 db in 0.1 steps
release time 0.0s - 10.0s in 0.1 steps

equaliser:
10 x bands 60, 170, 310, 600, 1k, 3k, 6k, 12k, 14k, 16k
-12..12 in 1 steps
range 5-20db in 1 steps
could have separate left/right eq's if required.
presets - load, save etc.

phase invert - checkbox per channel.

sound 3d
3d amplification - 0% - 100% in 1% steps

echo/delay
delay 0-3000ms in 9ms steps
gain 0-100% in 1% steps
kill main signal checkbox
highpass checkbox
number of echos 1-10

maybe include dsp worx logo in settings screen?

q. do we need separate settings per source? per stream? how about radio vs. mp3 vs. video? video may be multichannel too.

*)


(*
Idea for Empeg/Tivo style search:

Search takes input string and runs select count and select * where maxrows < 20 from content
where xIndex like "string%". xindex is one of the following:

Tivo style:
Remove word "The" and any punctuation, uppercase and store title

Empeg style:
As Tivo, but then convert each char to telephone keypad equivalent and store.

After each character entered, rerun the search query.
*)

(* How to use colour keyed textures - not ideal, pixel shading is faster technique
   but requires reasonable hardware support. This technique may be h/w accelerated
   so should be okay. Could use this for rendering opaque Active X control into a
   locked texture (e.g. for flash movies).

   http://www.codeproject.com/cs/media/3DAlphaTransparency.asp

   This is the crucial method to use:
   public void CreateVertexBuffer()
{
    //load the bitmap file, and use Magenta as the color key
    PanelTexture = Direct3D.TextureLoader.FromFile(
                         TDDevice,
                         TextureFile,
                         0,
                         0,
                         1,
                         Direct3D.Usage.None,
                         Direct3D.Format.Unknown,
                         Direct3D.Pool.Managed,
                         Direct3D.Filter.None,
                         Direct3D.Filter.None,
                         System.Drawing.Color.Magenta.ToArgb());
}

  Although we will need to use a corresponding method to load from a DC or memory buffer
  each frame.
*)

(* Thoughts: plugins / embedding

Plugin rendering:
Add a new interface to MediateServer com object - IMediateRendering
Add a method to this to begin render - return a DC, and end render.

*)

(*
other stuff to think about:

screen transitions. specifically around timing of events. e.g. a jump action
from a control - how do we arrange this so one screen fades out, we jump and
another fades in seamlessly. Or, how do we perform a x-fade between two screens?

persistence. Should also
persist appropriate metadata so that we return to correct path for media browsers
and should retain playlists so they can resume from previous position. also need
media position too.

*)

(*TODO list:

 old code... we can achieve the same thing with Application.BringToFront

  // If mediate is still not the front window then bring it to the front
  if GetForegroundWindow <> FScreenForm.Handle then
  begin
    // The only reliable way to bring mediate to the front seems to be to
    // toggle it's topmost setting - the SetForegroundWindow API just flashes
    // the form icon in the task bar instead
    if FScreenForm.FormStyle = fsNormal then
    begin
      // Make the form stay on top, then reset to normal
      SetWindowPos(FScreenForm.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
      Application.ProcessMessages;
      SetWindowPos(FScreenForm.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
    end
    else
    begin
      // Make the form normal, then reset to stay on top
      SetWindowPos(FScreenForm.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
      Application.ProcessMessages;
      SetWindowPos(FScreenForm.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
    end;
  end;



enhancments:

main form:
add an option to turn off border somehow - only affects windowed mode. Need to think
about how we would drag/resize form with no border? should this be stored in prefs?
how about automatically hiding the border after a few seconds, show it on mouse mode?

container backgrounds:
add option to allow mediawindow to use any background when not rendering (e.g.
plasma or gradient fill) - abstract rendering decision to a higher level
alternatively, or perhaps also need to add option to background to render media
window if running (more difficult?) point sprites for 3d starfield? (see
VMRMulti sample in DirectShow SDK)


Picture loading during slideshow (use a thread to load pic in background)



List control:
Derive rendering etc. from Grid control, but highlight all columns at once for
selected row.

Grid/List controls:
Possible to have different fonts for different cells? Multiple text positions
per cell? Ability to use variable width rows/columns? Ability to render across
multiple cells. Ability to use variable size selection rectangle. Ability to
control movement increments...

Sounds:
add sound schemes!


Add support for default screen indicator in screens entry - not necessarily first one
- need to override GetDefaultLayout method below (from Screens):
  TAHMScreenLayoutList = class(TAHMUIObjectList)
  private
  protected
  public
    constructor Create; override;
    function AddScreenLayout(const InheritFrom, NewName: String): TAHMScreenLayout;
    function GetScreenLayout(const Name: String): TAHMScreenLayout;
    function GetDefaultLayout: TAHMScreenLayout;
  end;

Add additional ui control types:
we need scrolling container support (ability to move controls according to
layout requirements)
some form of automated scrolling menu?
memo boxes
listbox (simplified grid)
scrollbox - could this be a simplistic scrolling container?
rss viewer?
up/down controls?
animating controls (esp. images)
treeview
listview (could add variable individual column width/row height to grid for this?)

Add support for init action for interface descriptor - common to all screens:
this is a low priority, plus there aren't that many functions that can be called
with a global context. Although "oninit" should really be supported within
a theme descriptors globalactions section. - test this. DOESN'T WORK - we need
to add support for "oninit" actions for descriptors



// Stop application for debugging for specific condition:
if <some_condition> then asm int 3 end;



HOWTO: Use an uninstalled font:
Setting an alternative font for your forms is easy. But how to use your
specialized fonts without the need to fill up your user's FONTS directory?
Well, it's just a few lines, so here we go:

// first load it in the OnCreate event of a form:
procedure TForm1.FormCreate(Sender: TObject);
begin
  AddFontResource('c:\FONTS\MyFont.TTF');
  SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
end;

// before application terminates, we must free it:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  RemoveFontResource('C:\FONTS\MyFont.TTF');
  SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
end;


  // Query system metrics for window border sizes
  FMouseXOffset := GetSystemMetrics(SM_CXFRAME);
  FMouseYOffset := GetSystemMetrics(SM_CYFRAME) + // window frame
                   GetSystemMetrics(SM_CYCAPTION); // title bar
  FMenuYOffset := GetSystemMetrics(SM_CYMENU); // menu bar
*)


end.
